package com.gitee.cirnochat.common.event.listener;

import com.gitee.cirnochat.common.event.DeviceOfflineEvent;
import com.gitee.cirnochat.common.event.UserEvent;
import com.gitee.cirnochat.common.event.UserEventFactory;
import com.gitee.cirnochat.login.model.enums.DeviceType;
import com.gitee.cirnochat.user.model.enums.UserStatus;
import com.gitee.cirnochat.websocket.service.manager.SessionManager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.Message;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.MessageHeaderAccessor;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.messaging.SessionConnectEvent;

import java.security.Principal;
import java.util.Map;


@Slf4j
@Component
@RequiredArgsConstructor
public class WebSocketConnectListener implements ApplicationListener<SessionConnectEvent> {
    private final ApplicationEventPublisher eventPublisher;
    private final SessionManager sessionManager;

    @EventListener(classes = SessionConnectEvent.class)
    public void handleWebSocketConnectListener(SessionConnectEvent event) {
        Principal user = event.getUser();
        Message<byte[]> message = event.getMessage();
        StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
        if (user != null && accessor != null) {
            log.info("WebSocket 连接成功，用户ID: {}", user.getName());
            Map<String, Object> sessionAttributes = accessor.getSessionAttributes();
            // 从会话属性中获取设备信息
            String deviceId = (String) sessionAttributes.get("deviceId");
            DeviceType deviceType = DeviceType.fromValue(Integer.valueOf((String) sessionAttributes.get("deviceType")));
            String deviceName = (String) sessionAttributes.get("deviceName");
            Long userId = Long.parseLong(user.getName());
            // 查看是否有同种类设备在线
            sessionManager.getDeviceNode(userId, deviceType)
                    .ifPresent(deviceNode -> {
                        // 发布设备下线事件
                        eventPublisher.publishEvent(new DeviceOfflineEvent(event.getSource(), userId, deviceNode.getDeviceId(), deviceNode.getDeviceName(), deviceNode.getDeviceType()));
                    });
            // 记录登录中的设备信息
            sessionManager.register(userId, deviceId, deviceName, deviceType);
            // 创建事件对象
            UserEvent userEvent = UserEventFactory.createUserEvent(event.getSource(), userId, UserStatus.ONLINE,deviceId,deviceName,deviceType);
            // 在线状态后，发布消息推送事件
            eventPublisher.publishEvent(userEvent);
        }
    }

    @Override
    public void onApplicationEvent(SessionConnectEvent event) {}
}
